#pragma comment(linker, "/STACK:16777216")
#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>
#include <conio.h>
using namespace std;

//#define ONLINE_JUDGE

#ifndef ONLINE_JUDGE
    #define log printf
#else
    #define log
#endif

int readint(){     int x( -12345 );    cin >> x;    return x; }
int readchar(){    char x( 123 );    cin >> x;    return x; }


int test();

int main()
{
#ifndef ONLINE_JUDGE
    freopen("\\projects\\olimp\\timus\\input.txt", "r", stdin );
#endif

    test();

#ifndef ONLINE_JUDGE
    log("\n\nPress any key...");
    _getch();
#endif

    return 0;
}
////////////////////////////////////////////////////////////////////////////////////
int n=0; // номер максимального работника (1..n)
vector< int > rating;
vector< int > parent; // родитель вершины
vector< vector< int > > kids; // дети вершины

vector< pair< int, int > > depth; // first=расстояние до корня, second=номер вершины

int compute_depth( int node )
{
	if (depth[node].first == -1) // не рассчитано
	{
		if (parent[node] == 0) // корень дерева, безотцовщина
			depth[node].first = 0;
		else
			depth[node].first = compute_depth( parent[node] ) + 1;
	}
	return depth[node].first;
}


//int dp( int node )
//{
//	
//}

int test()
{
	n=readint();
	rating.resize(n+1);
	kids.resize(n+1);
	depth.resize(n+1);
	parent.resize(n+1, 0);
	for (int i=1; i<=n; i++)
	{
		rating[i] = readint();
		depth[i].first  = -1;
		depth[i].second = i;
	}


	while(1)
	{
		int kid = readint();
		int dad = readint();
		if (kid==0 && dad==0)
			break;

		kids[dad].push_back(kid);
		parent[kid] = dad;
	};

	
	for (int i=1; i<=n; i++)
		compute_depth(i);

	sort( depth.rbegin(), depth.rend() ); // сортируем по глубине

	// dp по поддеревьям
	vector< pair< int, int > > dp(n+1); 
	// dp[i].first - макс. сумма по поддереву при условии что i-я вершина (корень поддерева) включена
	// dp[i].second - макс. сумма по поддереву при условии что i-я вершина (корень поддерева) НЕ включена

	for (int i=0; i<n; i++) // идем от листьев к корню
	{
		int node = depth[i].second;
		dp[node].first = rating[node]; // включаем саму вершину
		dp[node].second = 0; // не включаем...
		for (int i=0; i<kids[node].size(); i++) // и сумму по деревьям детей
		{
			dp[node].first += dp[ kids[node][i] ].second; //  - при условии что сами дети не вкл
			dp[node].second += max( dp[ kids[node][i] ].first, dp[ kids[node][i] ].second ); // без ограничения на самих детей
		}		
	}

	int root = depth[n-1].second;
	int result = max( dp[root].first, dp[root].second );
	cout << result;

    return 0;
}